home *** CD-ROM | disk | FTP | other *** search
- VERSION 1.0 CLASS
- BEGIN
- MultiUse = -1 'True
- END
- Attribute VB_Name = "ObjPicture"
- Attribute VB_Creatable = False
- Attribute VB_Exposed = False
- Option Explicit
-
- ' Each ObjPicture object is a quadtree node.
- '
- ' If the object is a leaf node, its Objects
- ' collection contains the objects to draw.
- '
- ' Otherwise the object's children contain other
- ' ObjPicture objects.
-
- ' The maximum number of objects the node can hold.
- Const MAX_OBJECTS = 100
-
- ' The bounds this quadtree node represents.
- Public xmin As Single
- Public ymin As Single
- Public xmid As Single
- Public ymid As Single
- Public xmax As Single
- Public ymax As Single
-
- ' The objects, if this is a leaf node.
- Private Objects As Collection
-
- ' The quadtree children otherwise.
- Public NWchild As ObjPicture
- Public NEchild As ObjPicture
- Public SWchild As ObjPicture
- Public SEchild As ObjPicture
-
- ' ************************************************
- ' Find an object that contains this point.
- ' ************************************************
- Function NearestObject(x As Single, y As Single) As Object
- Dim obj As Object
-
- Set NearestObject = Nothing
- ' Bail out if we don't contain the point.
- If x < xmin Or x > xmax Or _
- y < ymin Or y > ymax _
- Then Exit Function
-
- ' Find the object.
- If Objects Is Nothing Then
- If y > ymid Then
- If x < xmid Then
- Set NearestObject = NWchild.NearestObject(x, y)
- Else
- Set NearestObject = NEchild.NearestObject(x, y)
- End If
- Else
- If x < xmid Then
- Set NearestObject = SWchild.NearestObject(x, y)
- Else
- Set NearestObject = SEchild.NearestObject(x, y)
- End If
- End If
- Else
- For Each obj In Objects
- If obj.Contains(x, y) Then
- Set NearestObject = obj
- Exit Function
- End If
- Next obj
- End If
- End Function
-
- ' ************************************************
- ' Set the Drawn properties of the objects.
- ' ************************************************
- Sub SetDrawn(value As Boolean)
- Dim obj As Object
-
- If Objects Is Nothing Then
- NWchild.SetDrawn value
- NEchild.SetDrawn value
- SWchild.SetDrawn value
- SEchild.SetDrawn value
- Else
- For Each obj In Objects
- obj.Drawn = value
- Next obj
- End If
- End Sub
-
- ' ************************************************
- ' Add an object to the Objects collection.
- '
- ' If this gives us too many, create child nodes
- ' and subdivide.
- ' ************************************************
- Sub Add(obj As Object)
- If Objects Is Nothing Then
- PlaceObject obj
- Else
- Objects.Add obj
- If Objects.Count > MAX_OBJECTS Then Divide
- End If
- End Sub
-
- ' ************************************************
- ' Create the children and divide the object.
- ' ************************************************
- Sub Divide()
- Dim obj As Object
-
- ' Create the children.
- Set NWchild = New ObjPicture
- NWchild.SetBounds xmin, xmid, ymid, ymax
-
- Set NEchild = New ObjPicture
- NEchild.SetBounds xmid, xmax, ymid, ymax
-
- Set SWchild = New ObjPicture
- SWchild.SetBounds xmin, xmid, ymin, ymid
-
- Set SEchild = New ObjPicture
- SEchild.SetBounds xmid, xmax, ymin, ymid
-
- ' Divide up the children.
- For Each obj In Objects
- PlaceObject obj
- Next obj
-
- ' Remove the Objects collection.
- Set Objects = Nothing
- End Sub
-
- ' ************************************************
- ' Set the bounds for this quadtree node.
- ' ************************************************
- Sub SetBounds(x1 As Single, x2 As Single, y1 As Single, y2 As Single)
- xmin = x1
- ymin = y1
- xmax = x2
- ymax = y2
- xmid = (xmin + xmax) / 2
- ymid = (ymin + ymax) / 2
- End Sub
- ' ************************************************
- ' Place this object in the proper child(ren).
- ' ************************************************
- Sub PlaceObject(obj As Object)
- Dim x1 As Single
- Dim x2 As Single
- Dim y1 As Single
- Dim y2 As Single
-
- obj.Bound x1, y1, x2, y2
- If y2 > ymid And x1 < xmid Then NWchild.Add obj
- If y2 > ymid And x2 > xmid Then NEchild.Add obj
- If y1 < ymid And x1 < xmid Then SWchild.Add obj
- If y1 < ymid And x2 > xmid Then SEchild.Add obj
- End Sub
-
- ' ************************************************
- ' Draw the picture on a Form, Printer, or
- ' PictureBox.
- ' ************************************************
- Sub Draw(canvas As Object, x1 As Single, y1 As Single, x2 As Single, y2 As Single)
- Dim obj As Object
- Dim oldcolor As Long
-
- ' Bail out if we don't intersect the region
- ' we're trying to draw.
- If x2 < xmin Or x1 > xmax Or _
- y2 < ymin Or y1 > ymax _
- Then Exit Sub
-
- ' Draw a red box around our display region.
- oldcolor = canvas.ForeColor
- canvas.ForeColor = RGB(255, 0, 0)
- canvas.Line (xmin, ymin)-(xmax, ymax), , B '@
- canvas.ForeColor = oldcolor
-
- If Objects Is Nothing Then
- NWchild.Draw canvas, x1, y1, x2, y2
- NEchild.Draw canvas, x1, y1, x2, y2
- SWchild.Draw canvas, x1, y1, x2, y2
- SEchild.Draw canvas, x1, y1, x2, y2
- Else
- For Each obj In Objects
- obj.Draw canvas
- Next obj
- End If
- End Sub
-
- ' ************************************************
- ' Start with an empty Objects collection.
- ' ************************************************
- Private Sub Class_Initialize()
- Set Objects = New Collection
- End Sub
-
-
-